package com.taplinker.client.im.activity;

import java.io.FileNotFoundException;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.TextView;

import com.taplinker.client.R;
import com.taplinker.client.core.ImageManager;
import com.taplinker.client.core.LocalFileManager;
import com.taplinker.client.widget.image.TaplinkerImageView;
import com.taplinker.core.util.ImageUtil;

public class PictureDetailActivity extends Activity {
	private static final int ERROR = -1;
	private static final int NEED_ZOOM = 1;
	private static final int NEED_DO_NONE = 2;
	private static final int NEED_DOWNLOAD = 3;
	private View titleBar;
	private View titleBack;
	private TextView titleRight;
	private TaplinkerImageView imageView;
	
	private long lastTime;
	
	private String imageLocalPath = "";
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.picture_detail);
		findView();
		init();
	}
	
	private void init() {
		titleBar.setVisibility(View.GONE);
		Intent it = getIntent();
		if(it.getStringExtra("FilePath").contains("http://")) {
			imageView.setImageUrl(it.getStringExtra("FilePath"));
			return;
		}
		if(!it.hasExtra("FilePath") || TextUtils.isEmpty(imageLocalPath = it.getStringExtra("FilePath"))) {
			imageView.setImageResource(R.drawable.img_loading_error);
			return;
		}
		if(LocalFileManager.getInstance().getImage2Dir().equals(imageLocalPath)) {
			try {
				imageView.setImageBitmap(ImageUtil.getLocalImage(imageLocalPath));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
			imageLocalPath = com.taplinker.client.core.image.ImageManager.getInstance().findMaxImageByMin(imageLocalPath);
		}
		switch (getPicState()) {
		case ERROR:
			imageView.setImageResource(R.drawable.img_loading_error);
			break;
		case NEED_DOWNLOAD:
			if(LocalFileManager.getInstance().getImageDir().equals(imageLocalPath)) {
				try {
					imageView.setImageBitmap(ImageUtil.getLocalImage(com.taplinker.client.core.image.ImageManager.getInstance().findMaxImageByMin(imageLocalPath)));
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
			}
			downloadImg();
			break;
		case NEED_ZOOM:
			zoomImg();
			break;
		case NEED_DO_NONE:
			showImg();
			break;
		}
	}
	
	private int getPicState() {
		if(TextUtils.isEmpty(imageLocalPath)) {
			return ERROR;
		}
		if(!imageLocalPath.contains(LocalFileManager.getInstance().getAppRootDir())) {
			return NEED_ZOOM;
		}
		if(imageLocalPath.contains("http://")) {
			return NEED_DOWNLOAD;
		}
		return NEED_DO_NONE;
	}

	private void findView() {
		titleBar = findViewById(R.id.title_bar);
		titleBack = findViewById(R.id.title_back_bt);
		titleRight = (TextView) findViewById(R.id.title_right_bt);
		imageView = (TaplinkerImageView) findViewById(R.id.image_iv);
		imageView.setOnTouchListener(new MulitPointTouchListener(imageView));
		titleBack.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				setResult(RESULT_CANCELED);
				finish();
			}
		});
		titleRight.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				setResult(RESULT_OK);
				finish();
			}
		});
	}
	
	private void showImg() {
		BitmapFactory.Options option = new BitmapFactory.Options();
        Bitmap bm = BitmapFactory.decodeFile(imageLocalPath, option);
        if(bm == null) {
        	imageView.setImageResource(R.drawable.img_loading_error);
        } else {
        	imageView.setImageBitmap(bm);
        }
	}
	
	private void zoomImg() {
		com.taplinker.client.core.image.ImageManager.getInstance().loadImg(imageLocalPath, imageView, null);
	}
	
	private void downloadImg() {
		ImageManager.getInstance().loadImage(imageLocalPath, imageView, 0, 0, new ImageManager.LocalCallBack() {
			
			@Override
			public void updateProgres(long planSize, long curSize) {
				
			}
			
			@Override
			public void no() {
				imageView.setImageResource(R.drawable.img_loading_error);
			}
			
			@Override
			public void callBack(Object obj) {
				imageLocalPath = (String) obj;
			}
		});
	}
	
	class MulitPointTouchListener implements OnTouchListener {
		private static final int NONE = 0;
		private static final int DRAG = 1;
		private static final int ZOOM = 2;
		private Matrix matrix = new Matrix();
		private Matrix savedMatrix = new Matrix();
		private int mode = NONE;
		private PointF start = new PointF();
		private PointF mid = new PointF();
		private float oldDist = 1f;
		private ImageView iv;
		
		public MulitPointTouchListener(ImageView iv) {
			super();
			this.iv = iv;
		}

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			switch (event.getAction() & MotionEvent.ACTION_MASK) {
			case MotionEvent.ACTION_DOWN:
				lastTime = System.currentTimeMillis();
				matrix.set(iv.getImageMatrix());
				savedMatrix.set(matrix);
				start.set(event.getX(), event.getY());
				mode = DRAG;
				break;
			case MotionEvent.ACTION_POINTER_DOWN:
				oldDist = spacing(event);
				if (oldDist > 10f) {
					savedMatrix.set(matrix);
					midPoint(mid, event);
					mode = ZOOM;
				}
				break;
			case MotionEvent.ACTION_UP:
				if (mode == DRAG) {
					long time = System.currentTimeMillis();
					if((time - lastTime) < 350) {
						finish();
					}
				}
				mode = NONE;
				break;
			case MotionEvent.ACTION_POINTER_UP:
				mode = NONE;
				break;
			case MotionEvent.ACTION_MOVE:
				if (mode == DRAG) {
					matrix.set(savedMatrix);
					matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
				} else if (mode == ZOOM) {
					float newDist = spacing(event);
					if (newDist > 10f) {
						matrix.set(savedMatrix);
						float scale = newDist / oldDist;
						matrix.postScale(scale, scale, mid.x, mid.y);
					}
				}
				break;
			}
			iv.setScaleType(ScaleType.MATRIX);
			iv.setImageMatrix(matrix);
			return true;
		}
		
		@SuppressLint("FloatMath")
		private float spacing(MotionEvent event) {
			float x = event.getX(0) - event.getX(1);
			float y = event.getY(0) - event.getY(1);
			return FloatMath.sqrt(x * x + y * y);
		}

		private void midPoint(PointF point, MotionEvent event) {
			float x = event.getX(0) + event.getX(1);
			float y = event.getY(0) + event.getY(1);
			point.set(x / 2, y / 2);
		}     
	}

}
